﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpiceNet.Circuits
{
    public class CircuitConfiguration
    {
        /// <summary>
        /// Get an enumeration of integration methods
        /// </summary>
        public enum IntegrationMethods
        {
            Trapezoidal = 0x01,
            Gear = 0x02
        }

        /// <summary>
        /// Get the current (global) temperature
        /// </summary>
        public double Temperature;

        /// <summary>
        /// Get the current (global) nominal temperature
        /// </summary>
        public double NominalTemperature;

        /// <summary>
        /// Get the maximum amount of iterations for DC-type solving
        /// </summary>
        public int DcMaxIterations;

        /// <summary>
        /// Get the maximum amount of iterations for DC transfer curve-type solving
        /// </summary>
        public int DcTrcvMaxIterations;

        /// <summary>
        /// The integration method used for transient simulations
        /// </summary>
        public IntegrationMethods IntegrationMethod;

        /// <summary>
        /// Get the maximum amount of iterations for transient-type solving
        /// </summary>
        public int TranMaxIter;

        /// <summary>
        /// The number of steps used when source-stepping for solving operating points
        /// </summary>
        public int NumSrcSteps;

        /// <summary>
        /// The number of steps used when gmin-stepping for solving operating points
        /// </summary>
        public int NumGminSteps;

        /// <summary>
        /// The absolute tolerance (general)
        /// </summary>
        public double AbsTol;

        /// <summary>
        /// The relative tolerance (general)
        /// </summary>
        public double RelTol;

        /// <summary>
        /// The tolerance on charge equations
        /// </summary>
        public double ChgTol;

        /// <summary>
        /// The tolerance on voltages
        /// </summary>
        public double VoltTol;

        /// <summary>
        /// The global value for Gmin
        /// </summary>
        public double Gmin;

        /// <summary>
        /// The default length used for MOSFET devices
        /// </summary>
        public double DefaultMosL;

        /// <summary>
        /// The default width used for MOSFET devices
        /// </summary>
        public double DefaultMosW;

        /// <summary>
        /// The default drain area used for MOSFET devices
        /// </summary>
        public double DefaultMosAD;

        /// <summary>
        /// The default source area used for MOSFET devices
        /// </summary>
        public double DefaultMosAS;

        /// <summary>
        /// A flag that causes operating-point calculation to skip immediately to gmin-stepping
        /// </summary>
        public bool NoOpIter;

        /// <summary>
        /// A flag that will cause the circuit to store the operating point condition
        /// </summary>
        public bool KeepOpInfo;

        /// <summary>
        /// Constructor
        /// </summary>
        public CircuitConfiguration()
        {
            this.Gmin = 1e-12;
            this.AbsTol = 1e-12;
            // this.AbsTol = 1e-9;
            this.RelTol = 1e-3;
            this.ChgTol = 1e-14;
            this.VoltTol = 1e-6;

            this.TranMaxIter = 100;
            this.DcMaxIterations = 100;
            this.DcTrcvMaxIterations = 50;
            this.IntegrationMethod = IntegrationMethods.Trapezoidal;
            this.NumSrcSteps = 10;
            this.NumGminSteps = 10;

            this.Temperature = 300.15;
            this.NominalTemperature = 300.15;
            this.DefaultMosL = 1e-4;
            this.DefaultMosW = 1e-4;
            this.DefaultMosAD = 0;
            this.DefaultMosAS = 0;
            this.NoOpIter = false;
            this.KeepOpInfo = false;
        }

        /// <summary>
        /// Copy to another circuit configuration
        /// </summary>
        /// <param name="c"></param>
        public void CopyTo(CircuitConfiguration c)
        {
            c.Gmin = this.Gmin;
            c.AbsTol = this.AbsTol;
            c.RelTol = this.RelTol;
            c.ChgTol = this.ChgTol;
            c.VoltTol = this.VoltTol;

            c.TranMaxIter = this.TranMaxIter;
            c.DcMaxIterations = this.DcMaxIterations;
            c.DcTrcvMaxIterations = this.DcTrcvMaxIterations;
            c.IntegrationMethod = this.IntegrationMethod;
            c.NumSrcSteps = this.NumSrcSteps;
            c.NumGminSteps = this.NumGminSteps;

            c.Temperature = this.Temperature;
            c.NominalTemperature = this.NominalTemperature;
            c.DefaultMosL = this.DefaultMosL;
            c.DefaultMosW = this.DefaultMosW;
            c.DefaultMosAD = this.DefaultMosAD;
            c.DefaultMosAS = this.DefaultMosAS;
            c.NoOpIter = this.NoOpIter;
            c.KeepOpInfo = this.KeepOpInfo;
        }
    }
}
